﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mono.Cecil;
using System.Reflection;
using Mono.Cecil.Cil;
using System.IO;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.ILAst;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.NRefactory.CSharp;
using System.Collections;
using System.Diagnostics;
using Mono.Cecil.Pdb;

namespace devtm.Aop
{
    
    public static class MonoHelper
    {


        public static AssemblyDefinition LoadAssemblyMono(this string filename)
        {
            var cc = new FileInfo(filename).Directory.FullName;
            AssemblyDefinition Assembly;
            var resolver = new DefaultAssemblyResolver();
            resolver.AddSearchDirectory(cc);

            string pdbFilename = GetPdbFilename(filename);

            if (File.Exists(pdbFilename))
            {

                var PdbProvider = new Mono.Cecil.Pdb.PdbReaderProvider();

                var ReaderParameters = new ReaderParameters
                {
                    ReadSymbols = true,
                    AssemblyResolver = resolver,
                    SymbolReaderProvider = PdbProvider
                };

                Assembly = AssemblyDefinition.ReadAssembly(filename, ReaderParameters);

            }
            else
            {
                var ReaderParameters = new ReaderParameters { ReadSymbols = false, AssemblyResolver = resolver };
                Assembly = AssemblyDefinition.ReadAssembly(filename, ReaderParameters);

            }

            return Assembly;

        }

        public static AssemblyDefinition LoadAssemblyCecil(this System.Reflection.Assembly assembly)
        {

            string filename = assembly.Location;

            var cc = new FileInfo(filename).Directory.FullName;

            var resolver = new CustomAssemblyResolver();

            resolver.AddSearchDirectory(cc);

            string pdbFilename = GetPdbFilename(filename);

            PdbReaderProvider PdbProvider;
            ReaderParameters ReaderParameters;
            AssemblyDefinition Assembly;


            if (File.Exists(pdbFilename))
            {

                PdbProvider = new Mono.Cecil.Pdb.PdbReaderProvider();

                ReaderParameters = new ReaderParameters
                {
                    ReadSymbols = true,
                    AssemblyResolver = resolver,
                    SymbolReaderProvider = PdbProvider
                };

                Assembly = AssemblyDefinition.ReadAssembly(filename, ReaderParameters);

            }
            else
            {
                ReaderParameters = new ReaderParameters { ReadSymbols = false, AssemblyResolver = resolver };
                Assembly = AssemblyDefinition.ReadAssembly(filename, ReaderParameters);

            }

            return Assembly;

        }




        private static string GetPdbFilename(string filename)
        {
            return Path.ChangeExtension(filename, ".pdb");
        }


        public static void AddRange<TResult>(this Mono.Collections.Generic.Collection<TResult> collection, IEnumerable<TResult> source)
        {

            foreach (TResult item in source)            
                collection.Add(item);            

        }

        

    }
}
